#ifndef __GPT_API__
#define __GPT_API__

#include <iostream>
#include <string>
#include <curl/curl.h>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

struct WriteData {
    std::string buffer;           // 用于缓存收到的完整事件数据
    std::string accumulated_content; // 用于累积 "delta.content" 的值
};

namespace Gpt {
    class ChatWithGpt {
    public:
        std::string system_content = "扮演一名narnat同学，手机管家";
        std::string model_name = "deepseek-chat";
        std::string session_token = "40cabf45-0ebd-4735-b91e-8c9d37b6d708";
        bool ifstream = true;

        std::string put_text_to_gpt_get_reply(std::string user_content) {
            // 构造请求的 JSON 数据
            json request_body;
            request_body["model"] = model_name; 
            request_body["messages"] = { 
                {{"role", "system"}, {"content", system_content}},
                {{"role", "user"}, {"content", user_content}}
            };
            request_body["temperature"] = 0.2;     
            request_body["stream"] = ifstream;       
            request_body["session_token"] = session_token; 

            std::string post_data = request_body.dump(); 

            CURL* curl = curl_easy_init(); // 初始化 libcurl
            if (!curl) {
                std::cerr << "Failed to initialize CURL" << std::endl;
                return "";
            }

            // 设置 HTTP 请求的头信息
            struct curl_slist* headers = NULL;
            headers = curl_slist_append(headers, "Content-Type: application/json"); 
            headers = curl_slist_append(headers, ("Authorization: Bearer " + api_key).c_str()); 

            // 配置 CURL 选项
            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());           
            curl_easy_setopt(curl, CURLOPT_POST, 1L);                   
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);        

            // 设置流式响应处理回调
            WriteData write_data; 
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); 
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_data);       

            // 执行 HTTP 请求
            CURLcode res = curl_easy_perform(curl);

            // 清理 libcurl 和资源
            curl_slist_free_all(headers); 
            curl_easy_cleanup(curl);      

            if (res != CURLE_OK) {
                std::cerr << "\n请求失败: " << curl_easy_strerror(res) << std::endl; 
                return "";
            }

            // 返回累积的内容
            return write_data.accumulated_content;
        }

    private:
        const std::string api_key = "MC-62F6042A1FCC42548F7023ED1FBEBDD6";
        const std::string url = "https://api.mindcraft.com.cn/v1/chat/completions";

        static size_t WriteCallback(void* ptr, size_t size, size_t nmemb, void* userdata) {
            WriteData* data = static_cast<WriteData*>(userdata);
            const char* content = static_cast<char*>(ptr);
            size_t total_size = size * nmemb;                    

            data->buffer.append(content, total_size); 

            size_t start_pos = 0;
            while (true) {
                size_t end_pos = data->buffer.find("\n\n", start_pos); 
                if (end_pos == std::string::npos) break;               

                std::string event = data->buffer.substr(start_pos, end_pos - start_pos); 
                start_pos = end_pos + 2;  

                if (event.compare(0, 6, "data: ") == 0) { 
                    std::string json_str = event.substr(6); 
                    try {
                        json j = json::parse(json_str); 

                        // 检查 JSON 数据中是否包含有效的 "choices" 键
                        if (j.find("choices") != j.end() && j["choices"].is_array() && !j["choices"].empty()) {
                            const auto& choice = j["choices"][0]; 

                            // 检查 "delta" 键是否存在且是对象类型
                            if (choice.find("delta") != choice.end() && choice["delta"].is_object()) {
                                const auto& delta = choice["delta"];

                                // 检查 "content" 键是否存在且是字符串类型
                                if (delta.find("content") != delta.end() && delta["content"].is_string()) {
                                    // 累积 "delta.content" 的值
                                    data->accumulated_content += delta["content"].get<std::string>();
                                    //std::cout << delta["content"].get<std::string>() << std::flush; // 输出内容
                                }
                            }
                        }
                    } catch (const std::exception& e) {
                        std::cerr << "\nJSON解析错误: " << e.what() << std::endl; 
                    }
                }
            }

            data->buffer.erase(0, start_pos); 
            return total_size;                
        }                        
    };
}

#endif